//
// Created by shen on 2024/10/30.
//

#ifndef CROSSPLATFORMPLAYER_DECODERBASE_H
#define CROSSPLATFORMPLAYER_DECODERBASE_H
#define MAX_PATH   2048


extern "C"{
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/frame.h>
#include <libavutil/time.h>
#include <libavcodec/jni.h>
};
#include "Decoder.h"
#include <thread>
#include <mutex>
#include <log.h>
#include<condition_variable>
using namespace std;
#define DELAY_THRESHOLD 100
enum DecoderState {
    STATE_UNKNOWN,
    STATE_DECODING,
    STATE_PAUSE,
    STATE_STOP
};

enum DecoderMsg {
    MSG_DECODER_INIT_ERROR,
    MSG_DECODER_READY,
    MSG_DECODER_DONE,
    MSG_REQUEST_RENDER,
    MSG_DECODING_TIME
};
class DecoderBase :public Decoder{
public:
    DecoderBase()= default;

    virtual ~DecoderBase()= default;

    void Start() override;

    void Pause() override;

    void Stop() override;
    //seek 到某个时间点播放
    void SeekToPosition(float position) override;
    virtual void ClearCache(){};
    virtual void UnInit();
    float GetDuration() override{
        return m_Duration * 1.0f / 1000;
    }
    virtual void SetMessageCallback(void* context, MessageCallback callback)
    {
        m_MsgContext = context;
        m_MsgCallback = callback;
    }
protected:
    virtual int Init(const char *url,AVMediaType mediaType);
    float GetCurrentPosition() override;
    [[nodiscard]] AVFormatContext *GetAVFormatContext() const {
        return m_AVFormatContext;
    }

    [[nodiscard]] AVCodecContext *GetCodecContext() const {
        return m_AVCodecContext;
    }

    virtual void OnDecoderReady()=0;

    virtual void OnDecoderDone() = 0;

public:

    //数据流索引
    int              m_StreamIndex = -1;
    //数据流的类型
    AVMediaType      m_MediaType = AVMEDIA_TYPE_UNKNOWN;
    char       m_Url[MAX_PATH] = {0};
    //封装格式上下文
    AVFormatContext *m_AVFormatContext = nullptr;
    //解码器上下文
    AVCodecContext  *m_AVCodecContext = nullptr;
    //解码器
    AVCodec         *m_AVCodec = nullptr;
    //总时长 ms
    long  m_Duration = 0;
    //编码的数据包
    AVPacket        *m_Packet = nullptr;
    //解码的帧
    AVFrame         *m_Frame = nullptr;

    //当前播放时间
    long             m_CurTimeStamp = 0;
    int InitFFDecoder();
    void UnInitDecoder();
    void DecodingLoop();
    virtual void OnFrameAvailable(AVFrame *frame) = 0;
    static void DoAVDecoding(DecoderBase *decoder);
    //启动解码线程
    void StartDecodingThread();

    int DecodeOnePacket();

    //更新显示时间戳
    void UpdateTimeStamp();
    //音视频同步
    long AVSync();
    //锁和条件变量
    mutex               m_Mutex;
    condition_variable  m_Cond;
    thread             *m_Thread = nullptr;
    //播放的起始时间
    long             m_StartTimeStamp = -1;
    volatile int  m_DecoderState = STATE_UNKNOWN;

    //seek position
    volatile float      m_SeekPosition = 0;
    volatile bool       m_SeekSuccess = false;

    void * m_MsgContext = nullptr;
    MessageCallback m_MsgCallback = nullptr;
};


#endif //CROSSPLATFORMPLAYER_DECODERBASE_H
